﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

#if !NET20
using System.Dynamic;
#endif

namespace Apewer
{

    /// <summary>文本字典模型。</summary>
    [Serializable]

#if NET20
    public partial class TextSet
#else
    public partial class TextSet : DynamicObject

#endif
    {

        const string Null = "";
        bool _autotrim = false;
        bool _locked = false;
        Dictionary<string, string> _origin;

        #region properties

        /// <summary>获取或设置字典内容。</summary>
        public string this[string key] { get { return Get(key); } set { Set(key, value); } }

        /// <summary>获取字典。</summary>
        internal Dictionary<string, string> Origin { get { return _origin; } }

        #endregion

        #region ctor

        internal bool Locked { get { return _locked; } set { _locked = value; } }

        private void Constructor(bool autotrim, Dictionary<string, string> origin)
        {
            _origin = new Dictionary<string, string>();
            _autotrim = autotrim;

            if (origin != null)
            {
                foreach (var kvp in origin)
                {
                    var key = kvp.Key;
                    if (_autotrim && key.Length > 0) key = key.Trim();
                    if (_origin.ContainsKey(key)) continue;

                    var value = kvp.Value;
                    if (_autotrim && value.Length > 0) value = value.Trim();
                    _origin.Add(key, kvp.Value ?? "");
                }
            }
        }

        #endregion

        #region methods

        /// <summary>构造函数。</summary>
        public TextSet(bool autotrim = false)
        {
            Constructor(autotrim, null);
        }

        /// <summary>构造函数：从指定字典中导入。</summary>
        public TextSet(Dictionary<string, string> origin, bool autotrim)
        {
            Constructor(autotrim, origin);
        }

        /// <summary>构造函数：从指定实例中导入。</summary>
        public TextSet(TextSet origin, bool autotrim)
        {
            Constructor(autotrim, (origin == null) ? null : origin.Origin);
        }

        /// <summary>构造函数：从指定实例中导入。</summary>
        public TextSet(ObjectSet<string> origin, bool autotrim)
        {
            Constructor(autotrim, (origin == null) ? null : origin.Origin);
        }

        private string Get(string key)
        {
            var contains = false;
            return Get(key, ref contains);
        }

        private string Get(string key, ref bool contains)
        {
            var k = string.IsNullOrEmpty(key) ? "" : ((_autotrim) ? key.Trim() : key);
            var value = Null;
            lock (_origin)
            {
                contains = _origin.ContainsKey(k);
                if (contains) value = _origin[k];
            }
            return value ?? Null;
        }

        private bool Set(string key, string value)
        {
            if (_locked) return false;
            var k = string.IsNullOrEmpty(key) ? "" : ((_autotrim) ? key.Trim() : key);
            var v = string.IsNullOrEmpty(value) ? "" : ((_autotrim) ? value.Trim() : value);
            lock (_origin)
            {
                if (_origin.ContainsKey(k))
                {
                    _origin[k] = v ?? Null;
                }
                else
                {
                    _origin.Add(k, v);
                }
            }
            return true;
        }

        #endregion

        #region operator

        /// <summary></summary>
        public static implicit operator TextSet(Dictionary<string, string> dictionary) => new TextSet(dictionary, false);

        /// <summary></summary>
        public static implicit operator Dictionary<string, string>(TextSet set) => set?._origin;

        #endregion

        #region dynamic

#if !NET20

        /// <summary></summary>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var contains = false;
            result = Get(binder.Name, ref contains);
            return contains;
        }

        /// <summary></summary>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            return Set(binder.Name, value as string);
        }

        /// <summary></summary>
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return _origin.Keys;
        }

#endif

        #endregion

    }

}
